﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Net;
using Lidgren.Network;
using System.Threading;

namespace NetComps
{
    public enum Headers
    {
        PeopleData,
        PersonName,
        Text
    }

    class Program
    {
        static List<Person> People;
        static NetPeerConfiguration Config;
        static NetClient Client;

        static void Main(string[] args)
        {
            SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
            People = new List<Person>();
            Config = new NetPeerConfiguration("Game");
            Client = new NetClient(Config);
            Client.Start();
            Client.Connect("localhost", 7777);
            Client.RegisterReceivedCallback(new SendOrPostCallback(ReceiveData));
            Console.WriteLine("Client started.");
            
            new Thread(new ThreadStart(delegate 
                {
                    string input;
                    
                    while ((input = Console.ReadLine()) != null)
                    {
                        string[] prms = input.Split(' ');

                        switch (prms[0])
                        {
                            case "/changename":

                                if ((prms.Length >= 2) && (prms[1].Length > 1))
                                {
                                    NetOutgoingMessage outmsg;
                                    outmsg = Client.CreateMessage();
                                    outmsg.Write((byte)Headers.PersonName);
                                    outmsg.Write(prms[1]);
                                    Client.SendMessage(outmsg, NetDeliveryMethod.UnreliableSequenced);
                                }
                                else
                                {
                                    Console.WriteLine("Wrong");
                                }

                                break;
                        }
                    }

                })).Start();
        }

        private static void ReceiveData(object peer)
        {
            NetIncomingMessage incmsg;
            NetOutgoingMessage outmsg;

            while ((incmsg = Client.ReadMessage()) != null)
            {
                switch (incmsg.MessageType)
                {
                    case NetIncomingMessageType.StatusChanged:

                        if ((NetConnectionStatus)incmsg.ReadByte() == NetConnectionStatus.Connected)
                        {
                            Console.WriteLine("Connected.");
                            outmsg = Client.CreateMessage();
                            outmsg.Write((byte)Headers.PeopleData);
                            Client.SendMessage(outmsg, NetDeliveryMethod.UnreliableSequenced);
                        }

                        break;

                    case NetIncomingMessageType.Data:

                        Headers header = (Headers)incmsg.ReadByte();

                        if (header == Headers.PeopleData)
                        {
                            Console.WriteLine("Test");
                            People.Clear();
                            int count = incmsg.ReadInt32();
                            for (int i = 0; i < count; i++)
                            {
                                Person person = new Person();
                                incmsg.ReadAllProperties(person);
                                person.Connection = Client.GetConnection(new IPEndPoint(IPAddress.Parse(person.IP), 7777));
                                Console.WriteLine("Name: {0}, Age: {1}, IP: {2}, Connection: {3}", person.Name, person.Age, person.IP, person.Connection.ToString());
                                People.Add(person);
                            }

                        }

                        break;
                }
            }
        }
    }

    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string IP { get; set; }
        public NetConnection Connection;
        public Person() { }
    }
}
